﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Collections.Specialized;
using Quartz.Impl;
using Quartz;
using autobackup.job;
using Quartz.Impl.Triggers;
using autobackup.util;
using System.Threading;
using System.IO;
using ZTO.PicTest.Utilities;
using System.Collections;

namespace autobackup
{
    public partial class Form1 : Form
    {

        public static Form1 instance;

        public Form1()
        {
            InitializeComponent();
            instance = this;
        }


        #region 数据库持久化job,未用

        private static IScheduler _sched = null;

        /// <summary>  
        /// 初始化数据库存储  
        /// </summary>  
        public void InitDbStore()
        {
            //持久化配置参考  
            //http://www.quartz-scheduler.net/documentation/quartz-2.x/tutorial/job-stores.html  
            //添加驱动类型  
            //位置：\Quartz\Impl\AdoJobStore\Common\dbproviders.properties  
            //1.首先创建一个作业调度池  
            var properties = new NameValueCollection();
            //存储类型  
            properties["quartz.jobStore.type"] = "Quartz.Impl.AdoJobStore.JobStoreTX, Quartz";
            //表明前缀  
            properties["quartz.jobStore.tablePrefix"] = "QRTZ_";
            //驱动类型  
            properties["quartz.jobStore.driverDelegateType"] = "Quartz.Impl.AdoJobStore.StdAdoDelegate, Quartz";
            //数据源名称  
            string DBName = "quartz_storage";
            //string DbPath = Grass.Config.ConfigHelper.GetAppSettingsValue("quartz_storage"); //获取config中 quartz_storage 节点内容  
            string DbPath = Application.StartupPath + "/quartz.db";

            //数据源名称  
            properties["quartz.jobStore.dataSource"] = DBName;
            //拼接连接属性名称  
            string conPropertieName = string.Format("quartz.dataSource.{0}.connectionString", DBName);
            //连接字符串  
            properties[conPropertieName] = string.Format("Data Source={0};Pooling=true;FailIfMissing=false;Version=3;UTF8Encoding=True;Journal Mode=DELETE;", DbPath);
            //拼接驱动属性名称  
            string proPropertieName = string.Format("quartz.dataSource.{0}.provider", DBName);
            properties[proPropertieName] = "SQLite-10102"; //新加的驱动名称  
            //Configuring AdoJobStore to use strings as JobDataMap values (recommended)  
            properties["quartz.jobStore.useProperties"] = "true";

            ISchedulerFactory sf = new StdSchedulerFactory(properties);
            _sched = sf.GetScheduler();
        }

        #endregion

        private void Form1_Load(object sender, EventArgs e)
        {
            //InitDbStore();

            initSchedule();
            initViews();
            initIcon();//初始化托盘图标
            initSkin();

            showJob();
        }


        private void initSchedule()
        {
            // construct a scheduler factory
            ISchedulerFactory schedFact = new StdSchedulerFactory();

            // get a scheduler
            _sched = schedFact.GetScheduler();

            _sched.Start();

            //显示一些数据到界面上
            IJobDetail job = _sched.GetJobDetail(jobKey);
            ITrigger trigger = _sched.GetTrigger(triggerKey);
            if (job != null)
            {
                //备份的路径
                var dataMap = job.JobDataMap;
                string pathFromStr = dataMap.GetString("pathFroms");
                string pathTo = dataMap.GetString("pathTo");
                if (pathFromStr != null)
                {
                    textFolderFrom.Text = pathFromStr;
                }
                if (pathTo != null)
                {
                    textFolderTo.Text = pathTo;
                }


                //间隔秒数
                if (trigger is ISimpleTrigger)
                {
                    var triggerx = trigger as ISimpleTrigger;
                    textInternal.Text = triggerx.RepeatInterval.Seconds + "";
                }
                else if (trigger is ICronTrigger)
                {
                    var triggerx = trigger as CronTriggerImpl;

                }

            }

        }

        private void initViews()
        {
            for (int i = 0; i < 24; i++)
            {
                comboHours.Items.Add(i);//时
            }
            for (int i = 0; i < 60; i++)
            {
                comboMinutes.Items.Add(i);//分
            }
            comboHours.SelectedIndex = 0;
            comboMinutes.SelectedIndex = 0;
        }

        private void initSkin()
        {
            new Sunisoft.IrisSkin.SkinEngine().SkinFile = "skins/Emerald.ssk";
        }

        private static string keyName = "backUpJob";
        private static string jobGroup = "group1";
        private JobKey jobKey = new JobKey(keyName, jobGroup);

        private static string triggerName = "myTrigger";
        private static string triggerGroup = "group1";
        private TriggerKey triggerKey = new TriggerKey(triggerName, triggerGroup);

        private bool isPathFormsValid()
        {
            string[] pathFroms = getPathForms();
            if (pathFroms.Length == 0)
            {
                MessageBox.Show("请选择要备份的文件夹", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return false;
            }

            for (int i = 0; i < pathFroms.Length; i++)
            {
                string path = pathFroms[i];
                if (!Directory.Exists(path))
                {
                    MessageBox.Show("目录 " + path + " 不存在", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return false;
                }
            }
            return true;
        }

        private bool isPathToValid()
        {
            //string[] pathTo = getPathTo();
            // if (pathTo == "")
            //  {
            //      MessageBox.Show("请选择备份到的文件夹", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            //      return false;
            //  }
            //  else if (!Directory.Exists(pathTo))
            //  {
            //      MessageBox.Show("备份到的文件夹并不存在", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            //      return false;
            //  }
            //  return true;
            string[] pathTos = getPathTo();
            if (pathTos.Length == 0)
            {
                MessageBox.Show("请选择备份到的文件夹", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return false;
            }

            for (int i = 0; i < pathTos.Length; i++)
            {
                string path = pathTos[i];
                if (!Directory.Exists(path))
                {
                    MessageBox.Show("备份到的文件夹目录 " + path + " 不存在", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    //MessageBox.Show("备份到的文件夹并不存在", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return false;
                }
            }
            return true;
        }

      
        /// <summary>
        /// 添加运行
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnRun_Click(object sender, EventArgs e)
        {

            if (isPathFormsValid() && isPathToValid())
            {

                try
                {
                    startProject();
                }
                catch (System.Exception ex)
                {
                    MessageBox.Show("任务发生了点问题，" + ex.Message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }


                richTextBox1.Text = "创建任务成功。";
            }

        }

        private void btnTest_Click(object sender, EventArgs e)
        {
            IJobDetail job = _sched.GetJobDetail(jobKey);
            string[] pathForms = textFolderFrom.Text.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
            for (int i = 0; i < pathForms.Length; i++)
            {
                pathForms[i] = pathForms[i].Trim();//去掉首尾空格
            }

            string[] pathTo = textFolderTo.Text.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
            for (int i = 0; i < pathTo.Length; i++)
            {
                pathTo[i] = pathTo[i].Trim();//去掉首尾空格
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //清空任务
            _sched.Clear();

            richTextBox1.Clear();
            richTextBox1.AppendText("清空任务完成!");


        }

        private void startProject()
        {
            string[] pathFroms = getPathForms();
            string[] pathTo = getPathTo();

            //清空之前的任务
            _sched.Clear();

            //任务数据
            JobDataMap jobDataMap = new JobDataMap();
            jobDataMap.Add("pathFroms", string.Join(Environment.NewLine, pathFroms));
            //jobDataMap.Add("pathTo", pathTo);
            jobDataMap.Add("pathTo", string.Join(Environment.NewLine, pathTo));

            // define the job and tie it to our BackUpJob class
            IJobDetail job = JobBuilder.Create<BackUpJob>()
                .WithIdentity(keyName, jobGroup)
                .UsingJobData(jobDataMap)
                .Build();


            ITrigger trigger;

            if (radioCron.Checked)
            {
                //cron job

                int hours = Convert.ToInt32(comboHours.Text);
                int minutes = Convert.ToInt32(comboMinutes.Text);

                CronScheduleBuilder cb;

                if (radioDay.Checked)
                {
                    cb = CronScheduleBuilder.DailyAtHourAndMinute(hours, minutes);
                }
                else
                {
                    cb = CronScheduleBuilder.WeeklyOnDayAndHourAndMinute(DayOfWeek.Wednesday, hours, minutes);
                }

                cb.InTimeZone(TimeZoneInfo.Local);

                trigger = TriggerBuilder.Create()
       .WithIdentity(triggerName, triggerGroup)
       .WithSchedule(cb)//TimeZoneInfo.FindSystemTimeZoneById("Central America Standard Time")
       .ForJob(jobKey)
       .Build();


                _sched.ScheduleJob(job, trigger);
            }
            else if (radioSimple.Checked)
            {
                //简单定时任务
                //间隔几秒
                int interval = Convert.ToInt32(textInternal.Text);

                // Trigger the job to run now, and then every 40 seconds
                trigger = TriggerBuilder.Create()
                 .WithIdentity(triggerName, triggerGroup)
                 .StartNow()
                 .WithSimpleSchedule(x => x
                     .WithIntervalInSeconds(interval)
                     .RepeatForever()
                     )
                 .Build();


                _sched.ScheduleJob(job, trigger);
            }

        }

        /// <summary>
        /// 界面上显示当前job
        /// </summary>
        public void showJob()
        {
            this.BeginInvoke(new Action(() =>
            {
                richTextBox1.Clear();
                IJobDetail job = _sched.GetJobDetail(jobKey);
                ITrigger trigger = _sched.GetTrigger(triggerKey);
                if (trigger is ISimpleTrigger)
                {
                    var triggerx = trigger as ISimpleTrigger;
                    log("正在运行:");
                    log("触发器类型:简单任务");

                    log("任务注册 :" + toLocalTime(triggerx.StartTimeUtc));
                    log("上次执行 :" + toLocalTime(triggerx.GetPreviousFireTimeUtc()));
                    log("下次执行 :" + toLocalTime(triggerx.GetNextFireTimeUtc()));

                    //log("已经执行了 " + triggerx.TimesTriggered + " 次");
                }
                else if (trigger is ICronTrigger)
                {
                    var triggerx = trigger as CronTriggerImpl;
                    string msg = "正在运行:";
                    msg = "触发器类型:定时任务" + Environment.NewLine;
                    msg += "任务注册 :" + toLocalTime(triggerx.StartTimeUtc) + Environment.NewLine;
                    msg += "上次执行 :" + toLocalTime(triggerx.GetPreviousFireTimeUtc()) + Environment.NewLine;
                    msg += "下次执行 :" + toLocalTime(triggerx.GetNextFireTimeUtc()) + Environment.NewLine;
                    //msg += "时间表达式 :" + Environment.NewLine + triggerx.GetExpressionSummary() + Environment.NewLine;


                    log(msg);
                }
            }));
        }

        private void log(string msg)
        {
            richTextBox1.AppendText(msg + Environment.NewLine);
        }

        public void logMain(string msg)
        {
            this.BeginInvoke(new Action<string>((message) =>
            {
                log(message);
            }), msg);
        }

        

        private DateTimeOffset toLocalTime(DateTimeOffset? offset)
        {
            if (offset != null)
            {
                return offset.Value.AddHours(8);//到北京时间
            }
            return DateTimeOffset.MinValue;
        }


        private bool userCancel = true;
        /// <summary>
        /// 点击窗口关闭的按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (userCancel)
            {
                return;
            }
            // 取消关闭窗体
            e.Cancel = true;
            // 将窗体变为最小化
            this.WindowState = FormWindowState.Minimized;
        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            _sched.Shutdown(false);
            this.Dispose();
        }

        #region 备份具体工作相关

        //private string[] pathFroms;
        //private string pathTo = "";

        private string[] getPathForms()
        {
            string[] pathForms = textFolderFrom.Text.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
            for (int i = 0; i < pathForms.Length; i++)
            {
                pathForms[i] = pathForms[i].Trim();//去掉首尾空格
            }
            return pathForms.Distinct().ToArray();
        }

        private string[] getPathTo()
        {
            //return textFolderTo.Text;
            string[] pathTos = textFolderTo.Text.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
            for (int i = 0; i < pathTos.Length; i++)
            {
                pathTos[i] = pathTos[i].Trim();//去掉首尾空格
            }
            return pathTos.Distinct().ToArray();
        }

        private string selectPath()
        {
            string foldPath = "";
            FolderBrowserDialog dialog = new FolderBrowserDialog();
            dialog.Description = "请选择文件路径";
            if (dialog.ShowDialog() == DialogResult.OK)
            {
                foldPath = dialog.SelectedPath;
            }
            return foldPath;
        }

        private void SortPathFroms()
        {
            string[] paths = getPathForms();

            if (paths.Length > 0)
            {
                textFolderFrom.Text = string.Join(Environment.NewLine, paths);

            }
            else
            {
                textFolderFrom.Text = "";
            }
        }

        private void SortPathTo()
        {
            string[] paths = getPathTo();

            if (paths.Length > 0)
            {
                textFolderTo.Text = string.Join(Environment.NewLine, paths);

            }
            else
            {
                textFolderTo.Text = "";
            }
        }

        /// <summary>
        /// 选择备份哪里
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSelectFrom_Click(object sender, EventArgs e)
        {
            string path = selectPath();

            SortPathFroms();

            if (path != "")
            {
                if (textFolderFrom.Text != "")
                {
                    textFolderFrom.Text += Environment.NewLine;//换行
                }
                textFolderFrom.Text += path;
            }
        }

        /// <summary>
        /// 选择备份到哪里
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSelectTo_Click(object sender, EventArgs e)
        {
            /*
            string path = selectPath();
            if (path != "")
            {
                textFolderTo.Text = path;
            }*/
            string path = selectPath();

            SortPathTo();

            if (path != "")
            {
                if (textFolderTo.Text != "")
                {
                    textFolderTo.Text += Environment.NewLine;//换行
                }
                textFolderTo.Text += path;
            }
        }

        /// <summary>
        /// 打开文件夹
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnOpenFrom_Click(object sender, EventArgs e)
        {
            SortPathFroms();
            if (isPathFormsValid())
            {
                string[] pathFroms = getPathForms();
                for (int i = 0; i < pathFroms.Length; i++)
                {
                    System.Diagnostics.Process.Start(pathFroms[i]);
                }
            }

        }

        private void btnOpenTo_Click(object sender, EventArgs e)
        {
            if (isPathToValid())
            {
                string[] pathTo = getPathTo();
                for (int i = 0; i < pathTo.Length; i++)
                {
                    System.Diagnostics.Process.Start(pathTo[i]);
                }
                //System.Diagnostics.Process.Start(pathTo);
            }

        }

        #endregion


        #region 托盘图标

        //创建托盘图标对象 
        Icon ico = new Icon("favicon.ico");
        //创建托盘菜单对象 
        ContextMenu notifyContextMenu = new ContextMenu();

        private void initIcon()
        {
            //设置鼠标放在托盘图标上面的文字 
            this.notifyIcon1.Text = "打开主界面";
        }

        private void Form1_SizeChanged(object sender, EventArgs e)
        {
            //判断是否选择的是最小化按钮 
            if (WindowState == FormWindowState.Minimized)
            {
                //托盘显示图标等于托盘图标对象 
                //注意notifyIcon1是控件的名字而不是对象的名字 
                notifyIcon1.Icon = ico;
                //隐藏任务栏区图标 
                this.ShowInTaskbar = false;
                //图标显示在托盘区 
                notifyIcon1.Visible = true;
            }
        }

        private void showWindow()
        {
            //判断是否已经最小化于托盘 
            if (WindowState == FormWindowState.Minimized)
            {
                //还原窗体显示 
                WindowState = FormWindowState.Normal;
                //激活窗体并给予它焦点 
                this.Activate();
                //任务栏区显示图标 
                this.ShowInTaskbar = true;
                //托盘区图标隐藏 
                this.notifyIcon1.Visible = false;
            }
        }

        /// <summary>
        /// 双击托盘图标
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            showWindow();
        }

        private void iconMenuItemShow_Click(object sender, EventArgs e)
        {
            showWindow();
        }

        #endregion

        /// <summary>
        /// 刷新任务状态按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnRefresh_Click(object sender, EventArgs e)
        {
            showJob();
        }

        /// <summary>
        /// 共享文件夹按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnShareTo_Click(object sender, EventArgs e)
        {
            try
            {
                string[] pathTo = getPathTo();
                //ShareFolder.Share(pathTo, "文件备份", "文件自动备份");
                for(int i = 0; i < pathTo.Length; i++)
                {
                    ShareFolder.Share(pathTo[i], "文件备份", "文件自动备份");
                }
                MessageBox.Show("共享文件夹成功", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (System.Exception ex)
            {
                MessageBox.Show("共享失败，" + ex.Message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }

        }

        private void iconMenuItemExit_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("是否确认退出程序？", "退出", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.OK)
            {
                userCancel = true;

                // 关闭所有的线程
                //this.Dispose();

                this.Close();

            }
        }

        private void btnBackUp_Click(object sender, EventArgs e)
        {
            if (isPathFormsValid() && isPathToValid())
            {
                string[] pathFroms = getPathForms();
                string[] pathTo = getPathTo();

                Dictionary<string, object> strs = new Dictionary<string, object>();
                strs.Add("pathFroms", string.Join(Environment.NewLine, pathFroms));
                //strs.Add("pathTo", pathTo);
                strs.Add("pathTo", string.Join(Environment.NewLine, pathTo));
                new Thread(new ParameterizedThreadStart((obj) =>
                {
                    var paths = obj as Dictionary<string, object>;
                    string pathFormStr = paths["pathFroms"] as string;
                    if (pathFormStr == null) {
                        Form1.instance.logMain("未获取要备份的文件夹目录");
                    }
                    string[] pathForms = pathFormStr.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);

                    var pathToStr = paths["pathTo"] as string;

                    if (pathToStr == null)
                    {
                        Form1.instance.logMain("未获取备份的文件夹目录");
                    }
                    string[] to = pathToStr.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
                    ZipHelper zip = new ZipHelper();
                    if (pathForms.Length == to.Length) {
                        for (int i = 0; i < pathForms.Length; i++)
                        {
                            ///FileUtil.startCopy(pathForms[i], to[i]);
                            
                            Hashtable ht = zip.GetAllFies(pathForms[i]);
                            string backdir = to[i];
                            foreach (string key in ht.Keys)
                            {
                                //Console.WriteLine(key);
                                if (isCompressFileCheckedChanged())
                                {
                                    string aFirstName = key.Substring(key.LastIndexOf("\\") + 1, (key.LastIndexOf(".") - key.LastIndexOf("\\") - 1));
                                    string file = backdir + "\\" + aFirstName + ".zip";
                                    zip.ZipFile(key, file);
                                    FileUtil.total++;
                                }
                                else {
                                    string file = backdir + "\\" + FileUtil.GetFileName(key);
                                    FileUtil.Copy(key, file);
                                }

                                if (isDelFileCheckedChanged())
                                {
                                    FileUtil.DeleteFile(key);
                                }

                            }
                            /*
                            foreach (string value in ht.Values)
                            {
                                Console.WriteLine(value);
                            }
                            */
                        }

                    }
                    
                    //复制文件

                    //更新form上面的显示信息
                    Form1.instance.showJob();
                    //Form1.instance.logMain("本次任务共处理文件 " + FileUtil.total + " 个, 不需要复制的文件 " + FileUtil.noCopy + "个");
                    Form1.instance.logMain("本次任务共处理文件 " + FileUtil.total + " 个, 不需要处理的文件 " + FileUtil.noCopy + " 个, 删除文件 " + FileUtil.delcount + " 个");

                })).Start(strs);
            }


        }


        private void radioDay_CheckedChanged(object sender, EventArgs e)
        {
            //throw new NotImplementedException();
        }

        private void textFolderTo_TextChanged(object sender, EventArgs e)
        {

        }


        public bool isDelFileCheckedChanged()
        {
            if (isDelFile.CheckState == CheckState.Checked)
            {

                return true;
            }
            return false;
        }

        public bool isCompressFileCheckedChanged()
        {
            if (isCompressFile.CheckState == CheckState.Checked)
            {

                return true;
            }
            return false;
        }

        private void label2_Click(object sender, EventArgs e)
        {

        }
    }

}
